package com.fgxia.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fgxia.user.domain.bo.UserInvoiceInfoBo;
import com.fgxia.user.domain.vo.OrderInvoiceVo;
import com.fgxia.user.domain.vo.UserInvoiceInfoVo;
import com.fgxia.user.service.IInvoiceInfoService;
import com.ruoyi.business.domain.InvoiceInfo;
import com.ruoyi.business.domain.InvoiceOrderRef;
import com.ruoyi.business.domain.OrderInfo;
import com.ruoyi.business.mapper.InvoiceInfoMapper;
import com.ruoyi.business.mapper.InvoiceOrderRefMapper;
import com.ruoyi.business.mapper.OrderInfoMapper;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.OrderStatus;
import com.ruoyi.common.utils.BeanCopyUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 发票信息
 *
 * @author yyt
 */
@Service
@RequiredArgsConstructor
public class InvoiceInfoService implements IInvoiceInfoService {

    private final InvoiceInfoMapper invoiceInfoMapper;

    private final OrderInfoMapper orderInfoMapper;

    private final InvoiceOrderRefMapper invoiceOrderRefMapper;

    /**
     * 查询当前用户可开票订单
     * @return
     */
    @Override
    public TableDataInfo<OrderInvoiceVo> selectInvoiceOrderByUserId(Long relevanceUserId, PageQuery pageQuery) {
        // 查询当前用户可开票订单
        // 查询条件：订单状态为已完成，剩余开票金额 > 0
        LambdaQueryWrapper<OrderInfo> lqw = new LambdaQueryWrapper();
        lqw.eq(OrderInfo::getOrderStatus, OrderStatus.COMPLETED.getCode())
            .eq(OrderInfo::getRelevanceUserId, relevanceUserId)
            .gt(OrderInfo::getRemainingInvoiceAmount, 0)
            .orderByDesc(OrderInfo::getUpdateTime);

        Page<OrderInfo> orderInfoPages = orderInfoMapper.selectPage(pageQuery.build(), lqw);

        IPage<OrderInvoiceVo> pages = orderInfoPages.convert(orderInfo -> BeanCopyUtils.copy(orderInfo, OrderInvoiceVo.class));
        return TableDataInfo.build(pages);
    }

    /**
     * 查询当前用户已开票订单
     * @return
     */
    @Override
    public TableDataInfo<UserInvoiceInfoVo> selectInvoicedByUserId(Long relevanceUserId, PageQuery pageQuery) {
        // 查询当前用户已开票记录
        LambdaQueryWrapper<InvoiceInfo> lqw = new LambdaQueryWrapper();
        lqw.eq(InvoiceInfo::getRelevanceUserId, relevanceUserId).orderByDesc(InvoiceInfo::getUpdateTime);

        Page<InvoiceInfo> invoiceInfoPage = invoiceInfoMapper.selectPage(pageQuery.build(), lqw);
        IPage<UserInvoiceInfoVo> pages = invoiceInfoPage.convert(invoiceInfo -> BeanCopyUtils.copy(invoiceInfo, UserInvoiceInfoVo.class));

        return TableDataInfo.build(pages);
        // todo 上面是根据发票记录，查询发票，未查询关联的订单，可能需要优化
//        List<Long> invoiceIds = invoiceInfoPage.getRecords().stream().map(InvoiceInfo::getInvoiceId).collect(Collectors.toList());
//        LambdaQueryWrapper<InvoiceOrderRef> luw = new LambdaQueryWrapper();
//        luw.in(InvoiceOrderRef::getInvoiceId, invoiceIds);
//
//        // 查询开票记录对应订单
//        List<InvoiceOrderRef> invoiceOrderRefs = invoiceOrderRefMapper.selectList(luw);
//        List<Long> orderIds = invoiceOrderRefs.stream().map(InvoiceOrderRef::getOwnerId).collect(Collectors.toList());
//
//        LambdaQueryWrapper<OrderInfo> orderLqw = new LambdaQueryWrapper();
//        orderLqw.in(OrderInfo::getOrderId, orderIds);
//        List<OrderInfo> orderInfos = orderInfoMapper.selectList(orderLqw);
//        IPage<OrderInvoiceVo> pages = invoiceInfoPage.convert(orderInfo -> BeanCopyUtils.copy(orderInfo, OrderInvoiceVo.class));
//        return TableDataInfo.build(pages);
    }

    /**
     * 开票
     * @param userInvoiceInfoBo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean createInvoices(UserInvoiceInfoBo userInvoiceInfoBo) {
        // 插入发票信息
        InvoiceInfo invoiceInfo = BeanCopyUtils.copy(userInvoiceInfoBo, InvoiceInfo.class);
        invoiceInfoMapper.insert(invoiceInfo);

        // 插入发票订单关联信息
        List<Long> orderIds = userInvoiceInfoBo.getOrderIds();
        Long invoiceId = invoiceInfo.getInvoiceId();
        List<InvoiceOrderRef> invoiceOrderRefs = new ArrayList<>();
        for (Long orderId : orderIds) {
            invoiceOrderRefs.add(new InvoiceOrderRef(invoiceId, orderId, ""));
        }
        invoiceOrderRefMapper.insertBatch(invoiceOrderRefs);

        // todo 这里将一个订单只能开一次发票，一次所有金额，不支持一个订单开多次发票，后期需支持再开发
        // 修改订单剩余开票金额
        LambdaUpdateWrapper<OrderInfo> luw = new LambdaUpdateWrapper();
        luw.eq(OrderInfo::getRelevanceUserId, userInvoiceInfoBo.getRelevanceUserId())
            .in(OrderInfo::getOrderId, orderIds)
            .set(OrderInfo::getRemainingInvoiceAmount, 0);
        int result = orderInfoMapper.update(luw);

        // todo 开发票后，异步发送邮件
        return result > 0;
    }

    @Override
    public UserInvoiceInfoVo selectOne(InvoiceInfo invoiceInfo) {
        LambdaQueryWrapper<InvoiceInfo> lqw = new LambdaQueryWrapper();
        lqw.eq(InvoiceInfo::getInvoiceId, invoiceInfo.getInvoiceId())
            .eq(InvoiceInfo::getRelevanceUserId, invoiceInfo.getRelevanceUserId());

        InvoiceInfo info = invoiceInfoMapper.selectOne(lqw);
        return BeanCopyUtils.copy(info, UserInvoiceInfoVo.class);
    }
}
